package com.lanchetech.service.impl;


import com.alibaba.fastjson.JSON;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.lanchetech.bean.request.SmsCodeReq;
import com.lanchetech.bean.response.BaseResp;
import com.lanchetech.common.constants.JypConstant;
import com.lanchetech.common.enums.ResultCode;
import com.lanchetech.common.util.IpUtil;
import com.lanchetech.dao.SmsMapper;
import com.lanchetech.entity.Sms;
import com.lanchetech.service.SmsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

@Service
public class SmsServiceImpl implements SmsService {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Value("${sms.accessKeyId}")
    private String accessKeyId;
    @Value("${sms.accessKeySecret}")
    private String accessKeySecret;

    @Autowired
    SmsMapper smsMapper;

    @Override
    public Boolean verifySms(String phone, String code) {
        // 验证码有效期5分钟，验证码最多错误4次，
        Date now = new Date();
        Sms sms = smsMapper.getLatestSmsInFiveMinutes(phone, new Date(now.getTime() - 5 * 60 * 1000), now);
        if (sms != null) {
            if (sms.getVerify() < JypConstant.MAX_REGISTER_SMS_CODE_VERIFY_COUNT) {
                if (sms.getCode().equals(code)) {
                    return true;
                } else {
                    sms.setVerify(sms.getVerify() + 1);
                    smsMapper.updateByPrimaryKeySelective(sms);
                }
            }
        }

        return false;
    }

    @Override
    public BaseResp sendSms(HttpServletRequest request, HttpSession session, SmsCodeReq req) {
        Boolean isValidateCaptcha = this.validateCaptcha(session.getAttribute("captchaKey"), req.getCaptchaCode());

        // 验证码错误
        if (!isValidateCaptcha) {
            session.removeAttribute("captchaKey");
            return new BaseResp(ResultCode.CAPTCHA_WRONG);
        }

        // 24小时内一个手机号最多发送5条
        Integer todaySmsCount = smsMapper.countTodaySms(req.getPhone());
        if (todaySmsCount > JypConstant.MAX_SMS_ONE_DAY) {
            return new BaseResp(ResultCode.EXCEED_SMS_LIMIT);
        }

        // 24小时内一个ip最多发送10条
        String ip = IpUtil.getIpAddr(request);
        Integer todaySmsCountByIp = smsMapper.countTodaySmsByIp(ip);
        if (todaySmsCountByIp > JypConstant.MAX_SMS_ONE_DAY_BY_IP) {
            return new BaseResp(ResultCode.EXCEED_SMS_LIMIT);
        }

        // 30s后可重新发送
        Integer hasSmsIn30 = smsMapper.hasSmsInThirtySeconds(req.getPhone(), new Date(System.currentTimeMillis() - 30000), new Date(System.currentTimeMillis()));

        if (hasSmsIn30 == null) {
            Random rand = new Random();
            Integer code = rand.nextInt(8000) + 1000;
//            Integer code = 1111;
            Sms sms = new Sms();
            sms.setIp(ip);
            sms.setPhone(req.getPhone());
            sms.setCode(code.toString());
            sms.setVerify(0);
            sms.setCreatedAt(new Date());
            smsMapper.insert(sms);
            session.removeAttribute("captchaKey");
            Boolean result = this.doSendSms(req.getPhone(), code.toString(), req.getType(), sms.getId().toString());
//            Boolean result = true;
            if (result) {
                return new BaseResp();
            } else {
                return new BaseResp(ResultCode.SEND_SMS_FAIL);
            }
        } else {
            return new BaseResp(ResultCode.TRY_LATER);
        }
    }

    private Boolean validateCaptcha(Object captcha, String code) {
        Long towMinutesTime = 120000L;
        Integer codeLength = 4;

        if (captcha == null || code == null || code.length() != codeLength) {
            return false;
        }

        Long time = System.currentTimeMillis();
        String[] captchaArray = captcha.toString().split(",");
        Long captchaTime = new Long(captchaArray[0]);
        if (time > captchaTime + towMinutesTime) {
            return false;
        }

        return code.equals(captchaArray[1]);
    }


    public Boolean doSendSms(String phone, String code, String smsType, String outId) {
        String templateCode = "SMS_219310034";
        switch (smsType) {
            // 用户注册验证码
            case "REGISTER":
                templateCode = "SMS_219350059";
                break;
            // 修改密码验证码
            case "FORGET_PASSWORD":
                templateCode = "SMS_219370067";
                break;
            // 信息变更验证码
            case "UPDATE_PHONE":
                templateCode = "SMS_219280055";
                break;
            default:
                break;
        }

        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);

        CommonRequest request = new CommonRequest();
        //request.setProtocol(ProtocolType.HTTPS);
        request.setMethod(MethodType.POST);
        request.setDomain("dysmsapi.aliyuncs.com");
        request.setVersion("2017-05-25");
        request.setAction("SendSms");
        request.putQueryParameter("RegionId", "cn-hangzhou");
        request.putQueryParameter("PhoneNumbers", phone);
        request.putQueryParameter("SignName", "小嗨全球好物");
        request.putQueryParameter("TemplateCode", templateCode);
        request.putQueryParameter("TemplateParam", "{\"code\":\"" + code + "\"}");
        request.putQueryParameter("OutId", outId);
        try {
            CommonResponse response = client.getCommonResponse(request);
            log.info("发送短信结果：{}", response.getData());
            return response.getData().indexOf("\"Code\":\"OK\"") > 0;
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public BaseResp sendVerificationSmsCode(HttpServletRequest request, SmsCodeReq req) {
        String ip = IpUtil.getIpAddr(request);

        // 30秒后可重新发送
        Integer hasSmsInTwoMinutes = smsMapper.hasSmsInThirtySeconds(req.getPhone(), new Date(System.currentTimeMillis() - 30000), new Date(System.currentTimeMillis()));

        if (hasSmsInTwoMinutes == null) {
            Random rand = new Random();
            Integer code = rand.nextInt(8000) + 1000;
            Sms sms = new Sms();
            sms.setIp(ip);
            sms.setPhone(req.getPhone());
            sms.setCode(code.toString());
            sms.setVerify(0);
            sms.setCreatedAt(new Date());
            smsMapper.insert(sms);
            Boolean result = this.doSendSms(req.getPhone(), code.toString(), req.getType(), sms.getId().toString());
            if (result) {
                return new BaseResp();
            } else {
                return new BaseResp(ResultCode.SEND_SMS_FAIL);
            }
        } else {
            return new BaseResp(ResultCode.TRY_LATER);
        }
    }

    @Override
    public void sendShareCommissionSms(String name, String name2, String money, String phone) {
        String templateCode = "SMS_219390464";
        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);
        CommonRequest request = new CommonRequest();
        //request.setProtocol(ProtocolType.HTTPS);
        request.setMethod(MethodType.POST);
        request.setDomain("dysmsapi.aliyuncs.com");
        request.setVersion("2017-05-25");
        request.setAction("SendBatchSms");
        request.putQueryParameter("RegionId", "cn-hangzhou");
        request.putQueryParameter("TemplateCode", templateCode);

        List<String> phoneNumberJson = new ArrayList<>();
        List<String>  signNameJson = new ArrayList<>();
        phoneNumberJson.add(phone);
        signNameJson.add("小嗨全球好物");
        request.putQueryParameter("PhoneNumberJson", JSON.toJSONString(phoneNumberJson));
        request.putQueryParameter("SignNameJson", JSON.toJSONString(signNameJson));
        request.putQueryParameter("TemplateParamJson", "[{\"name\":\""+name+"\",\"money\":\""+money+"\"}]");
        try {
            CommonResponse response = client.getCommonResponse(request);
            log.info("发送分享奖励通知, 发送短信结果：{}", response.getData());
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void sendShopOrderSms(String remark, String phone) {
        String templateCode = "SMS_225335287";
        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);
        CommonRequest request = new CommonRequest();
        //request.setProtocol(ProtocolType.HTTPS);
        request.setMethod(MethodType.POST);
        request.setDomain("dysmsapi.aliyuncs.com");
        request.setVersion("2017-05-25");
        request.setAction("SendBatchSms");
        request.putQueryParameter("RegionId", "cn-hangzhou");
        request.putQueryParameter("TemplateCode", templateCode);

        List<String> phoneNumberJson = new ArrayList<>();
        List<String>  signNameJson = new ArrayList<>();
        phoneNumberJson.add(phone);
        signNameJson.add("小嗨全球好物");
        request.putQueryParameter("PhoneNumberJson", JSON.toJSONString(phoneNumberJson));
        request.putQueryParameter("SignNameJson", JSON.toJSONString(signNameJson));
        request.putQueryParameter("TemplateParamJson", "[{\"status\":\""+"已下单"+"\",\"remark\":\""+remark+"\"}]");
        try {
            CommonResponse response = client.getCommonResponse(request);
            log.info("发送商家订单通知, 发送短信结果：{}", response.getData());
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            e.printStackTrace();
        }
    }
}
